﻿using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using Conducido.WcfMessageLogger.Services.Behaviors.Entities;
using Conducido.WcfMessageLogger.Services.Behaviors.Entities.Config;
using Conducido.WcfMessageLogger.Services.Behaviors.Logger;

namespace Conducido.WcfMessageLogger.Services.Behaviors
{
    /// <summary>
    /// Client messagelogger
    /// </summary>
    public class ClientMessagelogInspector : IClientMessageInspector
    {
        private MessageLogConfiguration _messageLogConfiguration;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="wayOfLogging"></param>
        /// <param name="serviceMessageLogTransport"></param>
        /// <param name="uri"></param>
        public ClientMessagelogInspector(MessageLogType wayOfLogging, ServiceMessageLogType serviceMessageLogTransport, string uri)
        {
            _messageLogConfiguration = new MessageLogConfiguration(wayOfLogging, serviceMessageLogTransport, uri);
        }

        public object BeforeSendRequest(ref Message request, IClientChannel channel)
        {
            DateTime timestamp = DateTime.Now.ToUniversalTime();
            if (request == null || request.IsEmpty)
            {
                return null;
            }
            var logOperator = new LogOperator(request, _messageLogConfiguration);
            logOperator.LogOutgoing(timestamp, true);
            request = logOperator.CopyMessage();
            return logOperator.CreateCorrelatedInformation();
        }

        public void AfterReceiveReply(ref Message reply, object correlationState)
        {
            var timestamp = DateTime.Now.ToUniversalTime();
            if (reply == null || reply.IsEmpty ||
                    (reply.Headers.MessageVersion.Addressing == AddressingVersion.None
                    && reply.Headers.MessageVersion.Envelope == EnvelopeVersion.None)) //No need to log wsdl messages
            {
                return;
            }
            
            var wcfCallCorrelationState = (CorrelatedInformation)correlationState;

            var messageManager = new LogOperator(reply, wcfCallCorrelationState, _messageLogConfiguration);
            messageManager.LogIncoming(timestamp, true);

            reply = messageManager.CopyMessage();
        }
    }
}
